home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / GeometryTest / GTFile.c < prev    next >
Encoding:
Text File  |  1997-08-14  |  8.9 KB  |  367 lines  |  [TEXT/MPCC]

  1. // GTFile.c, file and metafile routines
  2.  
  3.  
  4. // system headers
  5. #include <Devices.h>
  6. #include <Dialogs.h>
  7. #include <DiskInit.h>
  8. #include <Fonts.h>
  9. #include <Menus.h>
  10. #include <PictUtils.h>
  11. #include <QDOffScreen.h>
  12. #include <QuickDraw.h>
  13. #include <Resources.h>
  14. #include <SegLoad.h>
  15. #include <StandardFile.h>
  16. #include <TextEdit.h>
  17. #include <ToolUtils.h>
  18.  
  19. #include "GTSupport.h"
  20. #include "GTFile.h"
  21.  
  22. #include "QD3D.h"
  23. #include "QD3DDrawContext.h"
  24. #include "QD3DRenderer.h"
  25. #include "QD3DShader.h"
  26. #include "QD3DCamera.h"
  27. #include "QD3DLight.h"
  28. #include "QD3DGeometry.h"
  29. #include "QD3DTransform.h"
  30. #include "QD3DGroup.h"
  31. #include "QD3DMath.h"
  32.  
  33. #include "QD3DStorage.h"
  34. #include "QD3DIO.h"
  35.  
  36.  
  37. //-------------------------------------------------------------------------------------------
  38. //
  39.  
  40. void InitDocumentData( DocumentHdl theDocument ) 
  41. {
  42.     TQ3Point3D        myOrigin = { 0, 0, 0 } ;
  43.     
  44.     // sanity check
  45.     if( theDocument == nil || (**theDocument).fWindow == nil )
  46.         return ;
  47.         
  48.     // Lock and load
  49.     HLock( (Handle)theDocument ) ;
  50.     
  51.     // sets up the 3d data for the scene
  52.     //    Create view for QuickDraw 3D.
  53.     (**theDocument).fView = MyNewView( (**theDocument).fWindow );
  54.  
  55.     // the main display group:
  56.     (**theDocument).fModel = NULL ;    
  57.     
  58.     // the drawing styles:
  59.     (**theDocument).fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  60.     (**theDocument).fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
  61.     (**theDocument).fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  62.  
  63.  
  64.     (**theDocument).fGroupScale = 1;                
  65.     (**theDocument).fGroupCenter = myOrigin ;    
  66.     
  67.     // set up an illumination shder for this document
  68.     (**theDocument).fShader = Q3PhongIllumination_New();        
  69.  
  70.     // set the rotation matrix the identity matrix
  71.     Q3Matrix4x4_SetIdentity(&(**theDocument).fRotation);    
  72.                     
  73.     // unlock the handle            
  74.     HUnlock((Handle) theDocument ) ;
  75.     
  76.     return ;
  77.     
  78. bail:
  79.     // either we failed getting the model or the view
  80.     // so we want to quit here
  81.     ExitToShell() ;
  82.     
  83. }
  84.  
  85. //-------------------------------------------------------------------------------------------
  86. //
  87.  
  88. void DisposeDocumentData( DocumentHdl theDocument )
  89. {
  90.     // Lock and load
  91.     HLock( (Handle)theDocument ) ;
  92.     
  93.     if( (**theDocument).fView ) 
  94.         Q3Object_Dispose((**theDocument).fView) ;                // the view for the scene
  95.  
  96.     if( (**theDocument).fModel )  
  97.         Q3Object_Dispose((**theDocument).fModel) ;                // object in the scene being modelled
  98.  
  99.     if( (**theDocument).fInterpolation )  
  100.         Q3Object_Dispose((**theDocument).fInterpolation) ;        // interpolation style used when rendering
  101.  
  102.     if( (**theDocument).fBackFacing )  
  103.         Q3Object_Dispose((**theDocument).fBackFacing) ;            // whether to draw shapes that face away from the camera
  104.  
  105.     if( (**theDocument).fFillStyle )  
  106.         Q3Object_Dispose((**theDocument).fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  107.  
  108.     HUnlock((Handle) theDocument ) ;
  109.     
  110.     // And free the storage used by the document handle
  111.     DisposHandle((Handle) theDocument);
  112. }
  113.  
  114. //-------------------------------------------------------------------------------------------
  115. //
  116. void HandleCloseWindow( WindowPtr theWindow )
  117. {
  118.     DocumentHdl     theDocument ;
  119.     
  120.     if( theWindow ) {
  121.         theDocument = (DocumentHdl) GetWRefCon( theWindow ) ;
  122.         DisposeWindow ( theWindow );
  123.         if( theDocument )
  124.             DisposeDocumentData( theDocument ) ;
  125.     }
  126.  
  127. }
  128.  
  129.  
  130. //-------------------------------------------------------------------------------------------
  131. // Create and init a document with the 3d stuff - gets called by both open and new
  132.  
  133. DocumentHdl    CreateDocument( void ) 
  134. {
  135.     DocumentHdl        theDocument;
  136.     WindowPtr        theWindow = nil ;
  137.     OSErr            theErr = noErr ;
  138.     
  139.     if(( theDocument = (DocumentHdl)NewHandleClear( sizeof(DocumentRec))) != nil )
  140.     {
  141.         theWindow = GetNewCWindow(128,nil,(WindowPtr)-1);
  142.         if( theWindow == nil ) 
  143.             return nil ;
  144.         
  145.         SetWRefCon( theWindow, (long)theDocument );
  146.         (**theDocument).fWindow = theWindow ;
  147.         
  148.         // initialise our document structure
  149.         InitDocumentData( theDocument ) ;
  150.     
  151.     }
  152.     else // handle the error
  153.         theErr = MemError() ;
  154.     
  155.     return theDocument ;        
  156. }
  157.  
  158. OSErr    HandleNewCommand( void )
  159. {
  160.     DocumentHdl    theDocument ;
  161.     OSErr        theErr = noErr ;
  162.     theDocument = CreateDocument() ;
  163.     if(theDocument == nil )
  164.     {
  165.         theErr = MemError() ;
  166.         if( theErr == noErr )
  167.         {
  168.             theErr = ResError() ;
  169.         }
  170.     
  171.     }
  172.     return theErr ;
  173. }
  174.  
  175. //-------------------------------------------------------------------------------------------
  176. //
  177. Boolean MetafileFileSpecify( FSSpec *theFile )
  178. {
  179.     StandardFileReply    theSFReply ;
  180.     SFTypeList            myTypes = { 'TEXT', '3DMF' } ;
  181.     const short            numTypes = 2 ;
  182.         
  183.     // Get the file name to open
  184.     StandardGetFile( nil, numTypes, myTypes, &theSFReply ) ;
  185.     
  186.     if( theSFReply.sfGood )
  187.         *theFile = theSFReply.sfFile ;
  188.     
  189.     // did the user cancel?
  190.     return theSFReply.sfGood ;
  191.     
  192. }
  193.  
  194. //-----------------------------------------------------------------------------------------------
  195. //
  196. OSErr    HandleOpenCommand( void )
  197. {
  198.     DocumentHdl    theDocument ;
  199.     OSErr        theErr = noErr ;
  200.     FSSpec        theFileSpec ;
  201.     
  202.     
  203.     theDocument = CreateDocument() ;
  204.     if(theDocument == nil )
  205.     {
  206.         theErr = MemError() ;
  207.         if( theErr == noErr )
  208.         {
  209.             theErr = ResError() ;
  210.         }
  211.         return theErr ;
  212.     }
  213.  
  214.     if(MetafileFileSpecify( &theFileSpec )) {
  215.     
  216.         WindowPtr        myWindow = (**theDocument).fWindow ;
  217.     
  218.         SetCursor(*(GetCursor(watchCursor)));
  219.         HLock((Handle)theDocument) ;
  220.         
  221.         // try to read the file into the main display group
  222.         if(((**theDocument).fModel = MyNewModelFromFile(&theFileSpec)) != NULL ) {        
  223.  
  224.             AdjustCamera(    theDocument,
  225.                             (myWindow->portRect.right - myWindow->portRect.left),
  226.                             (myWindow->portRect.bottom - myWindow->portRect.top) ) ;
  227.  
  228.             SetWTitle( myWindow, theFileSpec.name );
  229.             ShowWindow( myWindow ) ;
  230.             SetPort( myWindow ) ;
  231.     
  232.             SetCursor(&qd.arrow) ;
  233.             
  234.         }
  235.         
  236.         HUnlock((Handle)theDocument) ;
  237.     }
  238. }    
  239.  
  240.  
  241. //-----------------------------------------------------------------------------------------------
  242. // cleaned up from IM QuickDraw 3D pp 15-5
  243. static TQ3FileObject MyGetNewFile( FSSpec *myFSSpec, TQ3Boolean *isText )
  244. {
  245.     TQ3FileObject        myFileObj;
  246.     TQ3StorageObject        myStorageObj;
  247.     OSType                myFileType;
  248.     
  249.     FInfo                fndrInfo ;
  250.  
  251.     // we assume the FSSpec passed in was valid, get the file information
  252.     // we need to know the file type, this routine may get called by an appleEvent
  253.     // handler, so we can't assume a type, we need to get it from the fsspec.
  254.     
  255.     FSpGetFInfo( myFSSpec, &fndrInfo ) ;
  256.     
  257.     // pull out the file type
  258.     
  259.     myFileType = fndrInfo.fdType ;
  260.     
  261.     // Create new storage object and new file object 
  262.     if(((myStorageObj = Q3FSSpecStorage_New( myFSSpec )) == NULL) 
  263.         || ((myFileObj = Q3File_New()) == NULL)) 
  264.     {
  265.         if (myStorageObj != NULL) 
  266.             Q3Object_Dispose(myStorageObj);
  267.         return(NULL);
  268.     }
  269.  
  270.     // Set the storage for the file object
  271.     Q3File_SetStorage(myFileObj, myStorageObj);
  272.     Q3Object_Dispose(myStorageObj);
  273.  
  274.     if ((myFileType == '3DMF') || (myFileType == 'EO3D'))
  275.         *isText = kQ3False ;
  276.     else if (myFileType == 'TEXT')
  277.         *isText = kQ3True ;
  278.  
  279.     return (myFileObj);
  280. }
  281.  
  282.  
  283. //----------------------------------------------------------------------------------
  284. // read model from file object into the supplied group
  285.  
  286. static TQ3Status MyReadModelFromFile( TQ3FileObject theFile,TQ3GroupObject myGroup)
  287. {    
  288.     if(theFile != NULL) {
  289.     
  290.         TQ3Object            myTempObj ;
  291.         TQ3Boolean            isEOF ;
  292.                 
  293.     
  294.         // read objects from the file
  295.         do {
  296.         
  297.             myTempObj = Q3File_ReadObject( theFile );
  298.             
  299.             if( myTempObj != NULL ) {
  300.                 // we only want the object in our main group if we can draw it
  301.                 if ( Q3Object_IsDrawable( myTempObj) ) 
  302.                     Q3Group_AddObject( myGroup, myTempObj ) ;
  303.                 
  304.                 // we either added the object to the main group, or we don't care
  305.                 // so we can safely dispose of the object
  306.                 Q3Object_Dispose( myTempObj ) ;
  307.             }
  308.             
  309.             // check to see if we reached the end of file yet
  310.             isEOF = Q3File_IsEndOfFile( theFile );
  311.             
  312.         } while (isEOF == kQ3False);    
  313.     }
  314.     
  315.     if( myGroup != NULL )
  316.         return kQ3Success ;
  317.     else
  318.         return kQ3Failure ;
  319. }
  320.  
  321. //----------------------------------------------------------------------------------
  322. // attach a shader to the group
  323.  
  324. static TQ3Status MyAddShaderToGroup( TQ3GroupObject group )
  325. {
  326.     TQ3ShaderObject    illuminationShader = Q3PhongIllumination_New();
  327.  
  328.     Q3Group_AddObject(group, illuminationShader);
  329.     Q3Object_Dispose(illuminationShader);
  330.     return(kQ3Success);
  331. }
  332.  
  333. //----------------------------------------------------------------------------------
  334.  
  335. static TQ3GroupObject MyNewModelFromFile(FSSpec *theFileSpec)
  336. {
  337.     TQ3GroupObject        myGroup = NULL ;
  338.     TQ3Boolean            isText = kQ3False ;
  339.     TQ3FileMode            myFileMode = 0;
  340.     TQ3FileObject        theFile;
  341.     
  342.     //    Create a ordered group for the complete model.
  343.     if ((myGroup = Q3DisplayGroup_New()) == NULL )
  344.         return NULL;
  345.         
  346.     MyAddShaderToGroup( myGroup ) ;
  347.  
  348.     theFile = MyGetNewFile( theFileSpec, &isText ) ;
  349.     
  350.     if( isText == kQ3True )
  351.         myFileMode |= kQ3FileModeText;    // is it a text metafile??    
  352.  
  353.     // Open the file object
  354.     if( Q3File_OpenRead( theFile, &myFileMode ) != kQ3Success)
  355.         return  NULL ;
  356.  
  357.     if( MyReadModelFromFile( theFile, myGroup ) == NULL)
  358.         DebugStr("\pMetafile data read is null") ;
  359.     
  360.     Q3File_Close(theFile);            // close and dispose of the file object
  361.     Q3Object_Dispose(theFile);
  362.     
  363.     return myGroup ;
  364. }
  365.  
  366.  
  367.